iT邦幫忙

2022 iThome 鐵人賽

DAY 10
2
Software Development

30天學會Golang系列 第 10

Day10 - Go的單元測試 (下)

  • 分享至 

  • xImage
  •  

單元測試

上一篇我們提到單元測試,但除了檢查程式碼的正確率以外,還無法看出單元測試的重要性與強大,但前面有提到單元測試除了函數的正確性,此外也能看出函數的效能,因此這篇主要針對單元測試的效能,用上一篇 day09 的程式碼為例子

func BubbleSort(numbers []int) []int {
	unsortedUntilIndex := len(numbers) - 1
	swap := true

	for swap {
		swap = false
		for i := 0; i < unsortedUntilIndex; i++ {
			first := numbers[i]
			second := numbers[i+1]

			if first > second {
				numbers[i] = second
				numbers[i+1] = first
				swap = true
			}
		}
		unsortedUntilIndex--
	}

	return numbers
}

func Equals(t *testing.T, module string, given string, should string, result interface{}, expected interface{}) {
	message := createTestMessage(module, given, should, result, expected)

	if reflect.DeepEqual(result, expected) {
		// fmt.Print(message)
	} else {
		t.Errorf(message)
	}
}

// 自定義輸出格式
func createTestMessage(module string, given string, should string, result interface{}, expected interface{}) string {
	return fmt.Sprintf(`
%v
given:    %v
should:   %v
result:   %v
expected: %v
	`, module, given, should, result, expected)
}

// 單元測試,命名方式請遵守上面的6個規則,表格驅動測試
func TestBubbleSort(t *testing.T) {
	tests := []struct {
		input    []int
		expected []int
	}{
		{[]int{4, 2, 7, 1, 3}, []int{1, 2, 3, 4, 7}},
		{[]int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}},
	}

	for _, test := range tests {
		result := BubbleSort(test.input)
		Equals(t, "BubbleSort()", "Given slice of integers", "Should return slice sorted in ascending order", result, test.expected)
	}
}

如果想要查看代碼覆蓋率(代碼覆蓋是軟體測試中的一種度量,描述程式中原始碼被測試的比例和程度,所得比例稱為代碼覆蓋率),可以再相對應的路徑下在終端機中輸入以下指令:

go test -coverprofile=c.out 
go tool cover -html=c.out

就可以看到以下畫面:

https://ithelp.ithome.com.tw/upload/images/20220921/20150797kPhmbx7BFX.png

如果想要看 cpu 的使用情況,那麼可以透過以下指令,但是必須先安裝 Graphviz ,可在官網下載:

go test -bench . -cpuprofile cpu.out
go tool pprof cpu.out
(pprof) web

那結果如下:

https://ithelp.ithome.com.tw/upload/images/20220921/20150797kB3fpviF3u.png

可以看到,上面什麼也看不出來,因為測試的情境太簡單,所以基本上消耗不到什麼 cpu,因此在測試的地方 func TestBubbleSort 我稍微改了一下我們的表格驅動測試,先聲明,這只是為了展示,理論上後面的答案應該要輸入已知的正確資訊

func TestBubbleSort(t *testing.T) {

	input := make([]int, 10000)
	for i := 0; i < 10000; i++ {
		input[i] = rand.Intn(10000)
	}

	tests := []struct {
		input    []int
		expected []int
	}{
		// {[]int{4, 2, 7, 1, 3}, []int{1, 2, 3, 4, 7}},
		// {[]int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}},

		// 只為了展示,所以解答直接透過函數運算
		{input, BubbleSort(input)},
	}

	for _, test := range tests {
		result := BubbleSort(test.input)
		Equals(t, "BubbleSort()", "Given slice of integers", "Should return slice sorted in ascending order", result, test.expected)
	}
}

那就可以看到以下結果,總共耗時90ms,其中在執行 BubbleSort 的中佔了70ms,也可以透過這種方式知道究竟在執行程式時,哪些程式會佔用特別多的時間,那這些區域也是未來主要可以優化的區域

https://ithelp.ithome.com.tw/upload/images/20220921/20150797ddoOcYgwNa.png

第10天報到,呼~ 不知不覺竟然已經過了 1/3 的時間,好像感覺有變強了,不錯不錯,再接再厲

參考來源

  1. https://iulspop.medium.com/golang-setup-for-unit-testing-debugging-with-vs-code-ae02ba3e5024

代碼連結

https://github.com/luckyuho/ithome30-golang/tree/main/day10


上一篇
Day09 - Go的單元測試 (上)
下一篇
Day11 - Go的文檔制作
系列文
30天學會Golang31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言